#ifndef __COMMANDLINEDEF_H__
#define __COMMANDLINEDEF_H__

#include "plat/nonecopyable.h"
#include <vector>


#define COMMANDLINE_REPEAT_MAX 1
#define COMMANDLINE_WAIT_RESP_TIMEOUT 100  //ms

#define COMMANDLINE_RECV_MSGQ_MAX 256
#define COMMANDLINE_LINE_MAX 128

#define COMMANDLINE_THREAD_STACK_SIZE (192*4)

#define COMMANDLINE_HISTORY_MAX  5

//command line ret code
#define COMMANDLINE_RET_CODE_SUCC "succ"  //成功,如果成功，不需要写入params[0]
#define COMMANDLINE_RET_CODE_ERR "err"    //错误，具体错误查看 params[1]或者server 的log
#define COMMANDLINE_RET_CODE_UNCMD "uncmd" //未知指令

class CommandLineStream;
class CommandParamItem;
class CommandLineMgrBase;

//func 不使用lamda，节约ram
typedef void(*CommandHandleFuncPtr)(CommandParamItem &item);

class CommandParamItem : public NoneCopyable
{
public:
    std::string Name;
    std::vector<std::string> Params;

    std::string Resp; //调用函数写入，用来resp
    bool CancelSendTo = false;
    bool IsOk = false;

    //是否输入新行
    bool AckOnlyResp = false;

    CommandLineStream *Stream = nullptr;
    CommandLineMgrBase *CommandMgr = nullptr;

public:
    explicit CommandParamItem(){}
    virtual ~CommandParamItem(){}

public:
    inline CommandParamItem& AppendResp(const std::string &str)
    {
        Resp.append(str).append(" ");
        return *this;
    }

    inline CommandParamItem& Clear()
    {
        Resp.clear();
        return *this;   
    }

    inline CommandParamItem& Succ()
    {
        IsOk = true;
        return *this;
    }

    inline CommandParamItem& Error()
    {
        IsOk = false;
        AppendResp(COMMANDLINE_RET_CODE_ERR);
        return *this;
    }

    inline CommandParamItem& UnCmd()
    {
        IsOk = false;
        AppendResp(COMMANDLINE_RET_CODE_UNCMD);
        return *this;
    }
};

/// @brief 
//为了节约RAM空间，定义name和help为const，类型为char* 
struct CommandRegisterItem 
{
    const char* Name;
    const char* Help = nullptr;
    CommandHandleFuncPtr Handle = nullptr;
};

class CommnadParamsBuilder : public NoneCopyable
{
public:
    explicit CommnadParamsBuilder(){}
    virtual ~CommnadParamsBuilder(){}

public:
    CommnadParamsBuilder &operator << (const std::string &arg)
    {
        m_str.append(arg);
        m_str.append(" ");
        return *this;
    }

    inline CommnadParamsBuilder &End()
    {
        if(m_str.back() == ' ')
            m_str.pop_back();
        return *this;
    }

    inline std::string &Str()
    {
        return m_str;
    }

private:
    std::string m_str;
};

#endif // __COMMANDLINEDEF_H__
